package se.perp.c4.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import se.perp.c4.control.Main;
import se.perp.c4.control.iface.IReportCreator;
import se.perp.c4.model.Actor;
import se.perp.c4.model.Actor.Side;
import se.perp.c4.model.Deck;
import se.perp.c4.model.Territory.ETerritory;
import se.perp.c4.ui.MainPanel.Alignment;

public class MainWindow extends JFrame {

    private MainPanel panel;
    private InfoPanel infoPanel;
    private Container container;
    private ActorViewer actorViewer;
    private SpecialCard one,  two;
    private ImagePanel darkPortraitPanel = null,  lightPortraitPanel = null;
    private Side homeSide = Side.LIGHT;
    /** Opponent special card miniatures. */
    private SpecialCardMiniature oppOne,  oppTwo;
    private final String normalTitle = "Confrontation v" + Main.VERSION;
    private String playerName,  opponentName;

    public MainWindow(
            final ActorViewer actorViewer,
            final JMenuBar menuBar) {

        setTitle(normalTitle);
        this.actorViewer = actorViewer;

        setIconImage(Images.get(Images.Which.APPICON));
        setResizable(false);
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setJMenuBar(menuBar);
        setLayout(new BorderLayout());

        panel = new MainPanel();
        panel.setLocation(0, 0);
        add(panel, BorderLayout.CENTER);

        actorViewer.setLocation(panel.getWidth() - actorViewer.getWidth(), 0);
        panel.add(actorViewer);

        infoPanel = new InfoPanel();
        add(infoPanel, BorderLayout.SOUTH);

        pack();
        setLayout(null);

        container = panel;

        Point p = infoPanel.getLocation();
        BufferedImage bg = Images.get(Images.Which.TABLE);
        BufferedImage sub = bg.getSubimage(
                0, p.y, infoPanel.getWidth(), infoPanel.getHeight());
        Graphics2D g = sub.createGraphics();
        g.setColor(new Color(0,0,0,92));
        g.fillRect(0, 0, sub.getWidth(), sub.getHeight());
        infoPanel.setBgImage(sub);

    }

    public void setNormalTitleBar() {
        setTitle(normalTitle);
    }

    public void setNamedTitleBar() {
        setTitle(normalTitle + " - " + playerName + " vs. " + opponentName);
    }

    public void setUseMovementAssistHighlight(boolean b) {
        panel.setUseMovementAssistHighlight(b);
    }

    public void setHighlightedRegions(List<ETerritory> list, boolean doRepaint) {
        panel.setHighlightedRegions(list);
        if (doRepaint) {
            panel.repaint();
        }
    }

    public void setPalantirHighlight(ETerritory et) {
        panel.palantirHighlight(et);
        panel.repaint();
    }

    public void clearPalantirHighlight() {
        panel.clearPalantirHighlight();
        panel.repaint();
    }

    public void setHomeSide(Side side) {
        homeSide = side;
        RegionBounds.setHomeSide(side);
        panel.recreateMap();
    }

    public Container getContainer() {
        return container;
    }

    BufferedImage getBackgroundImage() {
        return panel.getBackgroundImage();
    }

    public void setReportButtonEnabled(boolean b) {
        infoPanel.setReportButtonEnabled(b);
    }

    public void setActorViewer(ActorViewer av) {
        if (actorViewer != null) {
            remove(actorViewer);
            actorViewer = av;
        }
        panel.add(actorViewer);
    }

    public void setContainer(Container p) {
        remove(container);
        setLayout(new BorderLayout());
        add(p, BorderLayout.CENTER);
        add(infoPanel, BorderLayout.SOUTH);
        pack();
        setLayout(null);
        container = p;
        if (p instanceof MainPanel) {
            panel = (MainPanel) p;
        }
    }

    public void addPieces(final PieceCollection pc) {
        for (GamePiece gp : pc) {
            panel.add(gp);
        }
    }

    public void addPieces(final List<GamePiece> pieces) {
        for (GamePiece gp : pieces) {
            panel.add(gp);
        }
    }

    public void setReportCreator(IReportCreator rc) {
        infoPanel.setReportCreator(rc);
    }

    public void setSpecialCardMiniatures(SpecialCardMiniature first, SpecialCardMiniature second) {
        if (this.oppOne != null) {
            panel.remove(oppOne);
        }
        if (this.oppTwo != null) {
            panel.remove(oppTwo);
        }
        this.oppOne = first;
        this.oppTwo = second;

        int gap = two.getX() - one.getX() - one.getWidth();
        int wSum = one.getWidth() + two.getWidth() + gap;

        int x1 = one.getX() + wSum / 2 - first.getWidth() - 5;
        int x2 = x1 + first.getWidth() + 10;
        int y = infoPanel.getY() - oppOne.getHeight() - 20;
        oppOne.setLocation(x1, y);
        oppTwo.setLocation(x2, y);
        panel.add(oppOne);
        panel.add(oppTwo);
    }

    public void setSpecialCards(SpecialCard one, SpecialCard two) {
        if (this.one != null) {
            panel.remove(this.one);
        }
        if (this.two != null) {
            panel.remove(this.two);
        }

        this.one = one;
        this.two = two;

        final int GAP = 20;
        int x = actorViewer.getX() + (actorViewer.getWidth() - one.getWidth()) / 2;
        int y1 = actorViewer.getY() + actorViewer.getHeight() + GAP;
        int y2 = y1 + one.getHeight() + GAP;
        one.setLocation(x, y1);
        two.setLocation(x, y2);
        panel.add(one);
        panel.add(two);

        one.setVisible(true);
        two.setVisible(true);
        one.repaint();
        two.repaint();
    }

    public void setMessage(Actor.Side side, String text) {
        boolean bottom =
                (homeSide == Side.LIGHT && side == Side.LIGHT) ||
                (homeSide == Side.DARK && side == Side.DARK);

        if (bottom) {
            panel.setDisplayMessage(Alignment.BOTTOM, text);
        } else {
            panel.setDisplayMessage(Alignment.TOP, text);
        }
    }

    public void setLightSideMessage(String text) {
        setMessage(Side.LIGHT, text);
    }

    public void setDarkSideMessage(String text) {
        setMessage(Side.DARK, text);
    }

    public void hideMessage(Actor.Side side) {
        setMessage(side, null);
    }

    public void setSpecialCardsResponsive(boolean b) {
        one.setResponsive(b);
        two.setResponsive(b);
    }

    public void setCenterMessage(String text) {
        panel.setCenterMessage(text);
    }

    public void showPortraits(Actor light, Actor dark, int lightVal, int darkVal, Actor.Side attackingSide) {

        String lightLabel, darkLabel;
        if (attackingSide == Actor.Side.LIGHT) {
            lightLabel = "Attacker";
            darkLabel = "Defender";
        } else {
            lightLabel = "Defender";
            darkLabel = "Attacker";
        }

        BufferedImage lightImg = Portraits.getLabeledNumberedNamedPortrait(
                light, lightLabel, lightVal);
        BufferedImage darkImg = Portraits.getLabeledNumberedNamedPortrait(
                dark, darkLabel, darkVal);

        hidePortraits();

        String template = "<html><body><center><b>%s</b> (%d)</center>%s</body></html>";

        lightPortraitPanel = new ImagePanel(lightImg);
        lightPortraitPanel.setToolTipText(String.format(template, light.name, light.attackValue, light.description));
        darkPortraitPanel = new ImagePanel(darkImg);
        darkPortraitPanel.setToolTipText(String.format(template, dark.name, dark.attackValue, dark.description));

        Point topPt = new Point(10, 10);
        Point bottomPt = new Point(
                actorViewer.getX() - lightPortraitPanel.getWidth() - 10,
                panel.getHeight() - lightPortraitPanel.getHeight() - 10);

        Point darkPt, lightPt;
        if (homeSide == Side.LIGHT) {
            darkPt = topPt;
            lightPt = bottomPt;
        } else {
            darkPt = bottomPt;
            lightPt = topPt;
        }

        darkPortraitPanel.setLocation(darkPt);
        lightPortraitPanel.setLocation(lightPt);

        panel.add(lightPortraitPanel);
        panel.add(darkPortraitPanel);
        panel.repaint();
    }

    public void hidePortraits() {
        if (lightPortraitPanel != null) {
            panel.remove(lightPortraitPanel);
            lightPortraitPanel = null;
        }
        if (darkPortraitPanel != null) {
            panel.remove(darkPortraitPanel);
            darkPortraitPanel = null;
        }
    }

//    public void setConnectionIndicatorVisible(boolean b) {
//        infoPanel.setConnectionIndicatorVisible(b);
//    }
//
//    public void setConnectionIndicatorOK() {
//        infoPanel.setConnectionIndicatorOK();
//    }
//
//    public void setConnectionIndicatorBad() {
//        infoPanel.setConnectionIndicatorBad();
//    }

    public void setCenterMessageVisible(boolean b) {
        panel.setCenterMessageVisible(b);
    }

    public void setMyDeck(Deck d) {
        infoPanel.setMyDeck(d);
    }

    public void setOpponentDeck(Deck d) {
        infoPanel.setOpponentDeck(d);
    }

    public void updateInfoPanel() {
        infoPanel.validate();
    }

    public void setMyScore(int myScore) {
        infoPanel.setMyScore(myScore);
    }

    public void setOpponentScore(int opponentScore) {
        infoPanel.setOpponentScore(opponentScore);
    }

    public void setPlayerName(String name) {
        playerName = name;
        infoPanel.setPlayerName(name);
    }

    public void setOpponentName(String name) {
        opponentName = name;
        infoPanel.setOpponentName(name);
    }
}
